package com.qingzhuge.scheduler.listener;

import com.qingzhuge.cache.IRedisLock;
import com.qingzhuge.cache.RedisLockUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobKey;
import org.quartz.Trigger;
import org.springframework.stereotype.Component;

import java.util.Map;

import static com.qingzhuge.common.Constants.LOCK_PREFIX;
import static com.qingzhuge.common.Constants.ROOT_CACHE_NAMESPACE;

/**
 * @author : zero.xiao
 * @description :
 * @date :2019-05-27 16:25
 * @modified :
 */
@Slf4j
@Component
public class TriggerListener implements org.quartz.TriggerListener {
    private String lockKey = ROOT_CACHE_NAMESPACE + LOCK_PREFIX + "%s:%s:lock";

    @Override
    public String getName() {
        return "qingtingTriggerListener";
    }

    @Override
    public void triggerFired(Trigger trigger, JobExecutionContext context) {

    }

    /**
     * 在 Trigger 触发后，Job 将要被执行时由 Scheduler 调用这个方法。
     * 假如这个方法返回 true，这个 Job 将不会为此次 Trigger 触发而得到执行。
     */
    @Override
    public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
        JobKey jobKey = trigger.getJobKey();
        String lockName = String.format(lockKey, jobKey.getGroup(), jobKey.getName());
        IRedisLock redisLock = RedisLockUtil.getRedisLock();
        //尝试加锁，最多等待2000毫秒，上锁后4000毫秒自动解锁
        boolean isLocked = redisLock.lock(lockName,context.getFireInstanceId());
        log.debug("lock result: {}", isLocked);
        if (isLocked) {
            Map<String, Object> paramsMap = context.getMergedJobDataMap();
            log.debug("获取到锁了，继续往下执行:{}", paramsMap);
            return false;
        } else {
            log.debug("未获取到锁，退出执行");
            return true;
        }
    }

    @Override
    public void triggerMisfired(Trigger trigger) {

    }

    @Override
    public void triggerComplete(Trigger trigger, JobExecutionContext context, Trigger.CompletedExecutionInstruction instruction) {
        log.info("调度执行完毕，开始释放锁");
        JobKey jobKey = trigger.getJobKey();
        String lockName = String.format(lockKey, jobKey.getGroup(), jobKey.getName());
        IRedisLock redisLock = RedisLockUtil.getRedisLock();
        Boolean unLock = redisLock.unLock(lockName, context.getFireInstanceId());
        if (unLock) {
            log.debug("调度释放锁成功:[{}]",context.getFireInstanceId());
        }else{
            log.debug("调度释放锁失败:[{}]",context.getFireInstanceId());
        }
    }
}
